/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * Nihongo
 * Copyright (C) Massimiliano Maniscalco 2011, 2012 <massi.neptune@yahoo.com>
 * 
 * Nihongo is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Nihongo is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "test_controller.h"
#include "parola.h"
#include "kanji.h"
#include "lezione.h"
#include "printable_window.h"
#include "kakikata_sheet.h"
#include "oboeru_sheet.h"
#include "test_scelta_mult_parole.h"
#include "test_scelta_mult_kanji.h"
#include "test_inserimento_parole.h"
#include "test_inserimento_numeri.h"


void TestController::
present_window ( void )
{
	_testSelWin->present ();
}

void TestController::
init_window ( void )
{
	update_lezione_pop_up_button ( _testParLezioneButton, _testParLezioneConnection, _testParLezionePopUpStore, &TestController::load_parole_in_tree_view );
	update_lezione_pop_up_button ( _testKnjLezioneButton, _testKnjLezioneConnection, _testKnjLezionePopUpStore, &TestController::load_kanji_in_tree_view );
	load_parole_in_tree_view ();
	load_kanji_in_tree_view ();
}

void TestController::
update_messaggio_statusbar ( int _ni, const char *_elemento, const char *_elementi )
{
	Glib::ustring _itemType;
	_mainStatus->pop ( _stsTestSelId );
	if ( _ni == 0 )
		_mainStatus->push ( Glib::ustring ( "Test non eseguibile" ), _stsTestSelId );
	else
	{
		Glib::ustring _tempoStr;
		crea_stringa_tempo_stimato ( _ni, _tempoStr );
		if ( _ni > 1 )
			_itemType.assign ( _elementi );
		else
			_itemType.assign ( _elemento );
		_mainStatus->push ( Glib::ustring::compose ( "Test su %1 %2, tempo necessario stimato: %3", Glib::ustring::format ( _ni ), _itemType, _tempoStr ), _stsTestSelId );
	}
}

void TestController::
crea_stringa_tempo_stimato ( int _ni, Glib::ustring &_str )
{
	if ( _ni > 0 )
	{
		short _secondi = ( _ni * 5 ) % 60;
		short _minuti = ( _ni * 5 ) / 60;
		if ( _minuti > 0 )
		{
			_str.append ( Glib::ustring::format ( _minuti ) );
			if ( _minuti == 1 )
				_str.append ( " minuto" );
			else
				_str.append ( " minuti" );
		}
		if ( _secondi > 0 )
		{
			if ( _minuti > 0 )
				_str.append ( " e " );
			_str.append ( Glib::ustring::format ( _secondi ) );
			if ( _secondi == 1 )
				_str.append ( " secondo" );
			else
				_str.append ( " secondi" );
		}
	}
}

void TestController::
connect_signals ( void )
{
	_testNotebook->signal_switch_page ().connect (sigc::mem_fun (this, &TestController::on_main_page_switch) );
	// toolbar
	_startTestButton->signal_clicked ().connect (sigc::mem_fun (this, &TestController::on_start_clicked) );
	// page parole
	_testParModeTipoRadioBtn1->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_parole_modo_tipo_radio_button_toggled), _testParModeTipoRadioBtn1 ) );
	_testParModeTipoRadioBtn2->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_parole_modo_tipo_radio_button_toggled), _testParModeTipoRadioBtn2 ) );
	_testConiuTipoRadioBtn1->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_coniugazioni_tipo_radio_button_toggled), _testConiuTipoRadioBtn1 ) );
	_testConiuTipoRadioBtn2->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_coniugazioni_tipo_radio_button_toggled), _testConiuTipoRadioBtn2 ) );
	_testCortRadioBtn1->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_cortese_radio_button_toggled), _testCortRadioBtn1 ) );
	_testCortRadioBtn2->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_cortese_radio_button_toggled), _testCortRadioBtn2 ) );
	_testCortRadioBtn3->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_cortese_radio_button_toggled), _testCortRadioBtn3 ) );
	_testNegRadioBtn1->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_negativo_radio_button_toggled), _testNegRadioBtn1 ) );
	_testNegRadioBtn2->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_negativo_radio_button_toggled), _testNegRadioBtn2 ) );
	_testNegRadioBtn3->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_negativo_radio_button_toggled), _testNegRadioBtn3 ) );
	_testParModeButton->signal_changed ().connect (sigc::mem_fun ( this, &TestController::on_parole_mode_changed) );
	_testParLezioneRadioBtn1->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_parole_lezione_radio_button_toggled), _testParLezioneRadioBtn1 ) );
	_testParLezioneRadioBtn2->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_parole_lezione_radio_button_toggled), _testParLezioneRadioBtn2 ) );
	_testParLezioneRadioBtn3->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_parole_lezione_radio_button_toggled), _testParLezioneRadioBtn3 ) );
	_testParLezioneConnection = _testParLezioneButton->signal_changed ().connect (sigc::mem_fun (this, &TestController::load_parole_in_tree_view) );
	_testParTipoButton->signal_changed ().connect (sigc::mem_fun (this, &TestController::on_parole_tipo_changed) );
	_testParDateButton->signal_changed ().connect (sigc::mem_fun (this, &TestController::on_parole_date_changed) );
	_testParEnableValButton->signal_toggled ().connect (sigc::mem_fun (this, &TestController::on_parole_enable_valutazione_toggled) );
	_testParValScale->signal_value_changed ().connect (sigc::mem_fun (this, &TestController::on_parole_value_changed) );
	// page kanji
	_testKnjModeRadioBtn1->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_kanji_modo_radio_button_toggled), _testKnjModeRadioBtn1 ) );
	_testKnjModeRadioBtn2->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_kanji_modo_radio_button_toggled), _testKnjModeRadioBtn2 ) );
	_testKnjLezioneRadioBtn1->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_kanji_lezione_radio_button_toggled), _testKnjLezioneRadioBtn1 ) );
	_testKnjLezioneRadioBtn2->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_kanji_lezione_radio_button_toggled), _testKnjLezioneRadioBtn2 ) );
	_testKnjLezioneRadioBtn3->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_kanji_lezione_radio_button_toggled), _testKnjLezioneRadioBtn3 ) );
	_testKnjLezioneConnection = _testKnjLezioneButton->signal_changed ().connect (sigc::mem_fun (this, &TestController::load_kanji_in_tree_view) );
	_testKnjDateButton->signal_changed ().connect (sigc::mem_fun (this, &TestController::on_kanji_date_changed) );
	_testKnjEnableValButton->signal_toggled ().connect (sigc::mem_fun (this, &TestController::on_kanji_enable_valutazione_toggled) );
	_testKnjValScale->signal_value_changed ().connect (sigc::mem_fun (this, &TestController::on_kanji_value_changed) );
	_kakiKataButton->signal_clicked ().connect (sigc::bind<Gtk::Button*>( sigc::mem_fun (this, &TestController::on_kanji_kaku_clicked), _kakiKataButton ) );
	_oboeteIruButton->signal_clicked ().connect (sigc::bind<Gtk::Button*>( sigc::mem_fun (this, &TestController::on_kanji_kaku_clicked), _oboeteIruButton ) );
	// page numeri
	_testNmrModoRadioBtn1->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_numeri_modo_radio_button_toggled), _testNmrModoRadioBtn1 ) );
	_testNmrModoRadioBtn2->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_numeri_modo_radio_button_toggled), _testNmrModoRadioBtn2 ) );
	_testNmrModoRadioBtn3->signal_toggled ().connect (sigc::bind<Gtk::RadioButton*>( sigc::mem_fun (this, &TestController::on_numeri_modo_radio_button_toggled), _testNmrModoRadioBtn3 ) );
	_testNmrEntry->signal_activate ().connect (sigc::mem_fun (this, &TestController::on_numeri_numero_domande_changed) );
}

void TestController::
on_main_page_switch ( Gtk::Widget *page, guint page_num )
{
	_testPage = page_num;
	switch ( _testPage )
	{
		case 0:
			update_messaggio_statusbar ( _paroleListStore->children().size(), "parola", "parole" );
			break;
		case 1:
			update_messaggio_statusbar ( _kanjiListStore->children().size(), "kanji", "kanji" );
			break;
		case 2:
			update_messaggio_statusbar ( atoi ( _testNmrEntry->get_text().raw().c_str() ), "numero", "numeri" );
			break;
	}
}

void TestController::
on_window_closed ( void )
{
	_testCtrlVoxChangedConnection.disconnect ();
	_testCtrlWinClosedConnection.disconnect ();
	delete _testCtrl;
	_testCtrl = 0;
	present_window ();
}

void TestController::
load_pop_up_button ( vector<Glib::ustring>::iterator _start, vector<Glib::ustring>::iterator _end, Glib::RefPtr<Gtk::ListStore> _popUpList )
{
	while ( _start != _end )
	{
		Gtk::TreeModel::iterator iter = _popUpList->append();
		Gtk::TreeModel::Row row = *iter;
		row[_buttonPopUpColumn->columnCell] = *_start;
		_start++;
	}
}

void TestController::
load_lezione_pop_up_button ( Glib::RefPtr<Gtk::ListStore> &_popUpList )
{
	_popUpList->clear();
	list<Lezione>::iterator _iterLezioni = _lezioni->begin();
	list<Lezione>::iterator _endLezioni = _lezioni->end();
	while ( _iterLezioni != _endLezioni )
	{
		Gtk::TreeModel::iterator iter = _popUpList->append();
		Gtk::TreeModel::Row row = *iter;
		Glib::ustring _temp ( _iterLezioni->get_nome() );
		row[_buttonPopUpColumn->columnCell] = _temp;
		_iterLezioni++;
	}
}

void TestController::
update_lezione_pop_up_button ( Gtk::ComboBox *_popUpButton, sigc::connection &_buttonBind, Glib::RefPtr<Gtk::ListStore> _listPopUpStore, void (TestController::*loadFunc)() )
{
	_buttonBind.disconnect ();
	Glib::ustring nomeLez ( "" );	
	if ( _listPopUpStore->children().size() > 0 )
	{
		if ( _popUpButton->get_active_row_number () > -1 )
		{
			Gtk::TreeModel::iterator _itNomeLez = _popUpButton->get_active ();
			Gtk::TreeModel::Row lezRow = *_itNomeLez;
			nomeLez.assign ( lezRow[_buttonPopUpColumn->columnCell] );
			Lezione _temp ( nomeLez );
			list<Lezione>::iterator _itLez = find ( _lezioni->begin(), _lezioni->end(), _temp );
			if ( _itLez == _lezioni->end() )
				nomeLez.assign ( "" );
		}
	}
	load_lezione_pop_up_button ( _listPopUpStore );
	if ( _listPopUpStore->children().size() > 0 )
	{
		if ( nomeLez == "" )
			_popUpButton->set_active ( 0 );
		else
		{
			int n = 0;
			Gtk::TreeModel::iterator _iter = _listPopUpStore->children().begin();
			Gtk::TreeModel::iterator _end = _listPopUpStore->children().end();
			while ( _iter != _end )
			{
				Gtk::TreeModel::Row _row = *_iter;
				if ( _row[_buttonPopUpColumn->columnCell] == nomeLez )
				{
					_popUpButton->set_active ( n );
					break;
				}
				n++;
				_iter++;
			}
		}
	}
	_buttonBind = _popUpButton->signal_changed ().connect (sigc::mem_fun (this, loadFunc) );
}

list<Lezione>::iterator TestController::
get_lezione_from_pop_up_button ( Gtk::ComboBox *_popUpButton )
{
	Gtk::TreeModel::iterator _itNomeLez = _popUpButton->get_active ();
	Gtk::TreeModel::Row lezRow = *_itNomeLez;
	Lezione _lezTemp ( lezRow[_buttonPopUpColumn->columnCell] );
	list<Lezione>::iterator _itLez = find ( _lezioni->begin(), _lezioni->end(), _lezTemp );
	if ( _itLez == _lezioni->end() )
		cerr << "Non trovo la lezione!" << endl;
	return _itLez;
}

void TestController::
on_start_clicked ( void )
{
	list<Parola> *_selezioneParole;
	list<Kanji> *_selezioneKanji;
	list<TestInserimentoNumeri::Numero> *_selezioneNumeri;
	char options[5];
	switch ( _testPage )
	{
		case 0:
			_selezioneParole = new list<Parola>;
			prepara_selezione_parole ( _selezioneParole );
			_testSelWin->hide ();
			if ( _testParoleModoTipo || _testParoleModalita == MOD_PAROLE_MEMORY || _testParoleModalita == MOD_PAROLE_READING )
			{
				_testCtrl = new TestSceltaMultParole ( _builder, _selezioneParole, _parole );
				_testCtrlVoxChangedConnection = _testCtrl->signal_parole_changed ().connect (sigc::mem_fun (this, &TestController::on_signal_parole_changed) );
				_testCtrlWinClosedConnection = _testCtrl->signal_window_closed ().connect (sigc::mem_fun (this, &TestController::on_window_closed) );
				options[0] = _testParoleModalita;
				options[1] = _testParVersoButton->get_active_row_number ();
				options[2] = _testParoleModoTipo;
				options[3] = _testParoleCortese;
				options[4] = _testParoleAffermativa;
			}
			else
			{
				_testCtrl = new TestInserimentoParole ( _builder, _selezioneParole );
				_testCtrlVoxChangedConnection = _testCtrl->signal_parole_changed ().connect (sigc::mem_fun (this, &TestController::on_signal_parole_changed) );
				_testCtrlWinClosedConnection = _testCtrl->signal_window_closed ().connect (sigc::mem_fun (this, &TestController::on_window_closed) );
				options[0] = _testParoleModalita;
				options[1] = _testParVersoButton->get_active_row_number ();
			}
			break;
		case 1:
			_selezioneKanji = new list<Kanji>;
			prepara_selezione_kanji ( _selezioneKanji );
			_testSelWin->hide ();
			_testCtrl = new TestSceltaMultKanji ( _builder, _selezioneKanji, _kanji );
			_testCtrlVoxChangedConnection = _testCtrl->signal_kanji_changed ().connect (sigc::mem_fun (this, &TestController::on_signal_kanji_changed) );
			_testCtrlWinClosedConnection = _testCtrl->signal_window_closed ().connect (sigc::mem_fun (this, &TestController::on_window_closed) );
			options[0] = _testKanjiModo;
			options[1] = _testKnjVersoButton->get_active_row_number ();
			break;
		case 2:
			_testSelWin->hide ();
			_testCtrl = new TestInserimentoNumeri ( _builder );
			_testCtrlWinClosedConnection = _testCtrl->signal_window_closed ().connect (sigc::mem_fun (this, &TestController::on_window_closed) );
			options[0] = _testNmrModo;
			options[1] = _testNmrVersoButton->get_active_row_number ();
			options[2] = atoi ( _testNmrEntry->get_text().raw().c_str() );
			options[3] = _testNmrMaxValButton->get_active_row_number ();
			break;
	}
	_testCtrl->run_test ( options );
}

void TestController::
load_parole_in_tree_view ( void )
{
	list<Lezione>::iterator _itLez = _lezioni->end();
	list<Glib::ustring> _listaParStr;
	_paroleListStore->clear();
	list<Parola>::iterator iterSet = _parole->begin();
	list<Parola>::iterator iterSet_end = _parole->end();
	time_t adesso = time ( NULL );
	unsigned int n = 0;
	if ( _testParoleLezione == 1 )
		_itLez = get_lezione_from_pop_up_button ( _testParLezioneButton );
	if ( _testParoleLezione == 2 )
	{
		list<Lezione>::iterator _iterLec = _lezioni->begin();
		list<Lezione>::iterator _iterLecEnd = _lezioni->end();
		while ( _iterLec != _iterLecEnd )
		{
			_listaParStr.insert ( _listaParStr.begin(), _iterLec->get_parole_list().begin(), _iterLec->get_parole_list().end() );
			_iterLec++;
		}
		_listaParStr.sort();
		_listaParStr.unique();
	}
	while (iterSet != iterSet_end)
	{
		bool _match = true;
		if ( _testParoleModoTipo == 0 && _testParoleModalita > 0 && !iterSet->has_kanji() )
			_match = false;
		if ( _match )
		{
			if ( _testParoleLezione > 0 )
			{
				switch ( _testParoleLezione )
				{
					case 1:
						if ( !_itLez->contiene_parola ( iterSet->get_kotoba() ) )
							_match = false;
						break;
					case 2:
						if ( find ( _listaParStr.begin(), _listaParStr.end(), iterSet->get_kotoba() ) != _listaParStr.end() )
							_match = false;
						break;
				}
			}
			if ( _match )
			{
				if ( _testParoleTipo > 0 )
				{
					char _filtroTipo;
					if ( _testParoleModoTipo )
					{
						if ( _testConiuTipoRadioBtn2->get_active () )
							_filtroTipo = _testParoleTipo + 3;
						else
							_filtroTipo = _testParoleTipo + 1;
					}
					else
						_filtroTipo = _testParoleTipo;
					if ( iterSet->get_tipo() != _filtroTipo )
						_match = false;
				}
				else
				{
					if ( _testParoleModoTipo )
					{
						char _itemTipo = iterSet->get_tipo();
						if ( _testConiuTipoRadioBtn2->get_active () )
						{
							if ( !iterSet->is_verbo () )
								_match = false;
						}
						else
						{
							if ( !iterSet->is_aggettivo () )
								_match = false;
						}
					}
				}
				if ( _match )
				{
					if ( _testParoleData > 0 )
					{
						double limite;
						double diff = difftime ( adesso, iterSet->get_data_esame ( _testParoleModalita ) );
						switch ( _testParoleData )
						{
							case 1: // piu' di una settimana
								limite = 604800.0;
								break;
							case 2: // piu' di un mese
								limite = 2592000.0;
								break;
							case 3: // piu' di un anno
								limite = 31536000.0;
								break;
							default:
								limite = 0.0;
								break;
						}
						if ( diff < limite )
							_match = false;
					}
					if ( _match )
					{
						if ( _testParoleEnableVal && iterSet->get_valutazione ( _testParoleModalita ) > _testParoleValutazione )
							_match = false;
						if ( _match )
						{
							Gtk::TreeModel::iterator iter = _paroleListStore->append();
							Gtk::TreeModel::Row row = *iter;
							row[_paroleListColumns->kotoba] = iterSet->get_kotoba();
							row[_paroleListColumns->yomikata] = iterSet->get_yomikata();
							row[_paroleListColumns->parola] = iterSet->get_gaikokugo ();
							row[_paroleListColumns->tipo] = iterSet->get_tipo_name();
							n++;
						}
					}
				}
			}
		}
		iterSet++;
	}
	if ( n == 0 && _startTestButton->get_sensitive () )
		_startTestButton->set_sensitive ( false );
	else
	{
		if ( n > 0 && !_startTestButton->get_sensitive () )
			_startTestButton->set_sensitive ( true );
	}
	if ( _testPage == 0 )
		update_messaggio_statusbar ( _paroleListStore->children().size(), "parola", "parole" );
}

void TestController::
on_parole_modo_tipo_radio_button_toggled ( Gtk::RadioButton *_button )
{
	if ( _button->get_active () )
	{
		if ( _button == _testParModeTipoRadioBtn1 )
			_testParoleModoTipo = 0;
		if ( _button == _testParModeTipoRadioBtn2 )
			_testParoleModoTipo = 1;
		_testParModePopUpStore->clear();
		if ( _testParoleModoTipo )
		{
			_testConiuTipoBox->set_visible ( true );
			_testCortBox->set_visible ( true );
			_testNegBox->set_visible ( true );
			on_coniugazioni_tipo_radio_button_toggled ( _testConiuTipoRadioBtn1->get_active () ? _testConiuTipoRadioBtn1 : _testConiuTipoRadioBtn2 );
		}
		else
		{
			_testConiuTipoBox->set_visible ( false );
			_testCortBox->set_visible ( false );
			_testNegBox->set_visible ( false );
			load_pop_up_button ( _testParModeStrings->begin(), _testParModeStrings->end() - 21, _testParModePopUpStore );
		}
		_testParModeButton->set_active ( 0 );
	}
}

void TestController::
on_coniugazioni_tipo_radio_button_toggled ( Gtk::RadioButton *_button )
{
	if ( _button->get_active () )
	{
		bool isVerb = ( _button == _testConiuTipoRadioBtn2 );
		_testParModePopUpStore->clear();
		_testParTipoPopUpStore->clear();
		if ( isVerb )
		{
			load_pop_up_button ( _testParModeStrings->begin() + 11, _testParModeStrings->end(), _testParModePopUpStore );
			load_pop_up_button ( _testParTipoStrings->begin() + 14, _testParTipoStrings->end(), _testParTipoPopUpStore );
		}
		else
		{
			load_pop_up_button ( _testParModeStrings->begin() + 3, _testParModeStrings->end() - 13, _testParModePopUpStore );
			load_pop_up_button ( _testParTipoStrings->begin() + 11, _testParTipoStrings->end() - 6, _testParTipoPopUpStore );
		}
		_testParModeButton->set_active ( 0 );
		_testParTipoButton->set_active ( 0 );
	}
}

void TestController::
on_cortese_radio_button_toggled ( Gtk::RadioButton *_button )
{
	if ( _button->get_active () )
	{
		if ( _button == _testCortRadioBtn1 )
			_testParoleCortese = 1;
		else
		{
			if ( _button == _testCortRadioBtn2 )
				_testParoleCortese = 0;
			else
				_testParoleCortese = -1;
		}
	}
}

void TestController::
on_negativo_radio_button_toggled ( Gtk::RadioButton *_button )
{
	if ( _button->get_active () )
	{
		if ( _button == _testNegRadioBtn1 )
			_testParoleAffermativa = 1;
		else
		{
			if ( _button == _testNegRadioBtn2 )
				_testParoleAffermativa = 0;
			else
				_testParoleAffermativa = -1;
		}
	}
}

void TestController::
on_parole_mode_changed ( void )
{
	char _prima = _testParoleModalita;
	_testParoleModalita = _testParModeButton->get_active_row_number ();
	if ( _testParoleModalita >= 0 && _prima != _testParoleModalita )
	{
		_testParVersoPopUpStore->clear();
		if ( _testParoleModoTipo )
		{
			load_pop_up_button ( _testParVersoStrings->begin() + 3, _testParVersoStrings->end(), _testParVersoPopUpStore );
		}
		else
		{
			_testParTipoPopUpStore->clear();
			load_pop_up_button ( _testParTipoStrings->begin(), _testParTipoStrings->end() - 9, _testParTipoPopUpStore );
			_testParTipoButton->set_active ( 0 );
			if ( _testParoleModalita == 0 )
				load_pop_up_button ( _testParVersoStrings->begin(), _testParVersoStrings->end() - 2, _testParVersoPopUpStore );
			else
				load_pop_up_button ( _testParVersoStrings->begin() + 2, _testParVersoStrings->end() - 1, _testParVersoPopUpStore );
		}
		_testParVersoButton->set_active ( 0 );
	}
}

void TestController::
on_parole_lezione_radio_button_toggled ( Gtk::RadioButton *_button )
{
	if ( _button->get_active () )
	{
		unsigned char _prima = _testParoleLezione;
		if ( _button == _testParLezioneRadioBtn1 )
			_testParoleLezione = 0;
		if ( _button == _testParLezioneRadioBtn2 )
		{
			_testParoleLezione = 1;
			_testParLezioneButton->set_sensitive ( true );
		}
		if ( _button == _testParLezioneRadioBtn3 )
			_testParoleLezione = 2;
		if ( _prima == 1 )
			_testParLezioneButton->set_sensitive ( false );
		load_parole_in_tree_view ();
	}
}

void TestController::
on_parole_tipo_changed ( void )
{
	char _prima = _testParoleTipo;
	_testParoleTipo = _testParTipoButton->get_active_row_number ();
	if ( _testParoleTipo >= 0 && _prima != _testParoleTipo )
		load_parole_in_tree_view ();
}

void TestController::
on_parole_date_changed ( void )
{
	_testParoleData = _testParDateButton->get_active_row_number ();
	load_parole_in_tree_view ();
}

void TestController::
on_parole_enable_valutazione_toggled ( void )
{
	_testParoleEnableVal = _testParEnableValButton->get_active ();
	_testParValScale->set_sensitive ( _testParoleEnableVal );
	load_parole_in_tree_view ();
}

void TestController::
on_parole_value_changed ( void )
{
	_testParoleValutazione = _testParValScale->get_value ();
	load_parole_in_tree_view ();
}

void TestController::
prepara_selezione_parole ( list<Parola> *_selezionate )
{
	if ( _selezionate )
	{
		Gtk::TreeModel::const_iterator _iter = _paroleListStore->children().begin();
		Gtk::TreeModel::const_iterator _end = _paroleListStore->children().end();
		while ( _iter != _end )
		{
			Gtk::TreeModel::Row _row = *_iter;
			list<Parola>::iterator _it;
			Parola _temp;
			_temp.set_kotoba ( _row[_paroleListColumns->kotoba] );
			_temp.set_yomikata ( _row[_paroleListColumns->yomikata] );
			_temp.set_gaikokugo ( _row[_paroleListColumns->parola] );
			_temp.set_tipo_from_name ( _row[_paroleListColumns->tipo] );
			_it = find ( _parole->begin(), _parole->end(), _temp );
			if ( _it != _parole->end() )
				_selezionate->push_back ( *_it );
			else
				cerr << "Errore: non trovo " << _temp.get_yomikata().raw() << endl;
			_iter++;
		}
	}
}

void TestController::
on_signal_parole_changed ( const Parola &verbum )
{
	list<Parola>::iterator _iter = find ( _parole->begin(), _parole->end(), verbum );
	if ( _iter != _parole->end() )
	{
		unsigned short index = _testParoleModoTipo ? 3 : _testParoleModalita;
		_iter->set_valutazione ( index, verbum.get_valutazione ( index ) );
		_iter->set_data_esame ( index, verbum.get_data_esame ( index ) );
		_iter->set_test_svolti ( verbum.get_test_svolti () );
		commit_vox_changed.emit ();
	}
}

void TestController::
load_kanji_in_tree_view ( void )
{
	list<Lezione>::iterator _itLez = _lezioni->end();
	list<Glib::ustring> _listaKnjStr;
	_kanjiListStore->clear();
	list<Kanji>::iterator iterSet = _kanji->begin();
	list<Kanji>::iterator iterSet_end = _kanji->end();
	time_t adesso = time ( NULL );
	unsigned int n = 0;
	if ( _testKanjiLezione == 1 )
		_itLez = get_lezione_from_pop_up_button ( _testKnjLezioneButton );
	if ( _testKanjiLezione == 2 )
	{
		list<Lezione>::iterator _iterLec = _lezioni->begin();
		list<Lezione>::iterator _iterLecEnd = _lezioni->end();
		while ( _iterLec != _iterLecEnd )
		{
			_listaKnjStr.insert ( _listaKnjStr.begin(), _iterLec->get_kanji_list().begin(), _iterLec->get_kanji_list().end() );
			_iterLec++;
		}
		_listaKnjStr.sort();
		_listaKnjStr.unique();
	}
	while (iterSet != iterSet_end)
	{
		bool _match = true;
		if ( _testKanjiLezione > 0 )
		{
			Glib::ustring _knjStr = iterSet->get_kanji();
			switch ( _testKanjiLezione )
			{
				case 1:
					if ( !_itLez->contiene_kanji ( _knjStr ) )
						_match = false;
					break;
				case 2:
					if ( find ( _listaKnjStr.begin(), _listaKnjStr.end(), _knjStr ) != _listaKnjStr.end() )
						_match = false;
					break;
			}
		}
		if ( _match )
		{
			if ( _testKanjiData > 0 )
			{
				double limite;
				double diff = difftime ( adesso, iterSet->get_data_esame ( _testKanjiModo ) );
				switch ( _testKanjiData )
				{
					case 1: // piu' di una settimana
						limite = 604800.0;
						break;
					case 2: // piu' di un mese
						limite = 2592000.0;
						break;
					case 3: // piu' di un anno
						limite = 31536000.0;
						break;
					default:
						limite = 0.0;
						break;
				}
				if ( diff < limite )
					_match = false;
			}
			if ( _match )
			{
				if ( _testKanjiEnableVal && iterSet->get_valutazione ( _testKanjiModo ) > _testKanjiValutazione )
					_match = false;
				if ( _match )
				{
					Gtk::TreeModel::iterator iter = _kanjiListStore->append();
					Gtk::TreeModel::Row row = *iter;
					row[_kanjiListColumns->kanji] = iterSet->get_kanji();
					row[_kanjiListColumns->tratti] = iterSet->get_tratti();
					row[_kanjiListColumns->radicale] = iterSet->get_radicale();
					n++;
				}
			}
		}
		iterSet++;
	}
	if ( n == 0 && _startTestButton->get_sensitive () )
		_startTestButton->set_sensitive ( false );
	else
	{
		if ( n > 0 && !_startTestButton->get_sensitive () )
			_startTestButton->set_sensitive ( true );
	}
	if ( _testPage == 1 )
		update_messaggio_statusbar ( _kanjiListStore->children().size(), "kanji", "kanji" );
}

void TestController::
on_kanji_modo_radio_button_toggled ( Gtk::RadioButton *_button )
{
	if ( _button->get_active () )
	{
		unsigned char _prima = _testKanjiModo;
		if ( _button == _testKnjModeRadioBtn1 )
			_testKanjiModo = 0;
		if ( _button == _testKnjModeRadioBtn2 )
			_testKanjiModo = 1;
		_testKnjVersoPopUpStore->clear();
		if ( _testKanjiModo == 0 )
			load_pop_up_button ( _testKnjVersoStrings->begin(), _testKnjVersoStrings->end() - 1, _testKnjVersoPopUpStore );
		else
			load_pop_up_button ( _testKnjVersoStrings->begin() + 2, _testKnjVersoStrings->end(), _testKnjVersoPopUpStore );
		_testKnjVersoButton->set_active ( 0 );
	}
}

void TestController::
on_kanji_lezione_radio_button_toggled ( Gtk::RadioButton *_button )
{
	if ( _button->get_active () )
	{
		unsigned char _prima = _testKanjiLezione;
		if ( _button == _testKnjLezioneRadioBtn1 )
			_testKanjiLezione = 0;
		if ( _button == _testKnjLezioneRadioBtn2 )
		{
			_testKanjiLezione = 1;
			_testKnjLezioneButton->set_sensitive ( true );
		}
		if ( _button == _testKnjLezioneRadioBtn3 )
			_testKanjiLezione = 2;
		if ( _prima == 1 )
			_testKnjLezioneButton->set_sensitive ( false );
		load_kanji_in_tree_view ();
	}
}

void TestController::
on_kanji_date_changed ( void )
{
	_testKanjiData = _testKnjDateButton->get_active_row_number ();
	load_kanji_in_tree_view ();
}

void TestController::
on_kanji_enable_valutazione_toggled ( void )
{
	_testKanjiEnableVal = _testKnjEnableValButton->get_active ();
	_testKnjValScale->set_sensitive ( _testKanjiEnableVal );
	load_kanji_in_tree_view ();
}

void TestController::
on_kanji_value_changed ( void )
{
	_testKanjiValutazione = _testKnjValScale->get_value ();
	load_kanji_in_tree_view ();
}

void TestController::
prepara_selezione_kanji ( list<Kanji> *_selezionate )
{
	Gtk::TreeModel::const_iterator _iter = _kanjiListStore->children().begin();
	Gtk::TreeModel::const_iterator _end = _kanjiListStore->children().end();
	while ( _iter != _end )
	{
		Gtk::TreeModel::Row _row = *_iter;
		list<Kanji>::iterator _it;
		Kanji _temp = Kanji ( _row[_kanjiListColumns->kanji] );
		_it = find ( _kanji->begin(), _kanji->end(), _temp );
		_selezionate->push_back ( *_it );
		_iter++;
	}
}

void TestController::
on_signal_kanji_changed ( const Kanji &knj )
{
	list<Kanji>::iterator _iter = find ( _kanji->begin(), _kanji->end(), knj );
	if ( _iter != _kanji->end() )
	{
		_iter->set_valutazione ( _testKanjiModo, knj.get_valutazione ( _testKanjiModo ) );
		_iter->set_data_esame ( _testKanjiModo, knj.get_data_esame ( _testKanjiModo ) );
		_iter->set_test_svolti ( knj.get_test_svolti () );
		commit_vox_changed.emit ();
	}
	else
		cerr << "Errore: non trovo il kanji" << endl;
}

void TestController::
on_kanji_kaku_clicked ( Gtk::Button *_button )
{
	DrawingKanjiSheet *drawArea;
	list<Kanji> *_selezioneKanji;
	_selezioneKanji = new list<Kanji>;
	prepara_selezione_kanji ( _selezioneKanji );
	int pagine = ( _selezioneKanji->size() / 40 ) + ( ( _selezioneKanji->size() % 40 ) > 0 );
	PrintableWindow *winDraw = new PrintableWindow ();
	winDraw->set_transient_for ( *_testSelWin );
	Gtk::ScrolledWindow *scrollWid = winDraw->get_scrolled_window ();
	if ( _button == _kakiKataButton )
		drawArea = new KakikataSheet ();
	else
		drawArea = new OboeruSheet ();
	drawArea->set_kanji_list ( _selezioneKanji );
	drawArea->set_size_request ( 560, 768 * pagine );
	winDraw->set_drawing_area ( drawArea );
	scrollWid->add ( *drawArea );
	winDraw->show_all_children ();
	winDraw->signal_hide ().connect (sigc::bind<Gtk::Window*>(sigc::mem_fun (this, &TestController::on_printable_window_closed), winDraw ) );
	winDraw->present ();
}

void TestController::
on_printable_window_closed ( Gtk::Window *_win )
{
	delete _win;
}

void TestController::
on_numeri_modo_radio_button_toggled ( Gtk::RadioButton *_button )
{
	if ( _button->get_active () )
	{
		if ( _button == _testNmrModoRadioBtn1 )
			_testNmrModo = 0;
		if ( _button == _testNmrModoRadioBtn2 )
			_testNmrModo = 1;
		if ( _button == _testNmrModoRadioBtn3 )
			_testNmrModo = 2;
		_testNmrVersoPopUpStore->clear();
		Glib::ustring _numVerso[3] = { "da cifre a hiragana", "da hiragana a cifre", "da kanji a hiragana" };
		vector<Glib::ustring> _numVersoS ( _numVerso, _numVerso + 3 );
		switch ( _testNmrModo )
		{
			case 0:
				load_pop_up_button ( _numVersoS.begin(), _numVersoS.end() - 1, _testNmrVersoPopUpStore );
				_testNmrMaxValButton->set_sensitive ( true );
				_testNmrEntry->set_sensitive ( true );
				break;
			case 1:
				load_pop_up_button ( _numVersoS.begin(), _numVersoS.end() - 1, _testNmrVersoPopUpStore );
				_testNmrMaxValButton->set_active ( 0 );
				_testNmrMaxValButton->set_sensitive ( false );
				_testNmrEntry->set_text ( "10" );
				_testNmrEntry->set_sensitive ( false );
				break;
			case 2:
				load_pop_up_button ( _numVersoS.begin() + 2, _numVersoS.end(), _testNmrVersoPopUpStore );
				_testNmrMaxValButton->set_sensitive ( false );
				_testNmrEntry->set_text ( "31" );
				_testNmrEntry->set_sensitive ( true );
				break;
		}
		_testNmrVersoButton->set_active ( 0 );
		update_messaggio_statusbar ( atoi ( _testNmrEntry->get_text().raw().c_str() ), "numero", "numeri" );
	}
}

void TestController::
on_numeri_numero_domande_changed ( void )
{
	update_messaggio_statusbar ( atoi ( _testNmrEntry->get_text().raw().c_str() ), "numero", "numeri" );
}
